package cn.szsys.integration.advice;

import cn.szsys.integration.ex.BaseException;
import cn.szsys.integration.ex.BusinessException;
import cn.szsys.integration.ex.enums.ExceptionEnum;
import cn.szsys.integration.util.R;
import jakarta.annotation.Resource;
import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @author Ryan
 * @since 2025-05-08
 **/
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class ControllerExceptionAdvice {
    @Resource
    private MultipartProperties multipartProperties;


    @ResponseBody
    @ExceptionHandler(value = Throwable.class)
    @ResponseStatus(HttpStatus.OK)
    public R<?> throwable(Throwable e) {
        R<?> r;
        if (e instanceof BusinessException be) {
            r = R.error(be.getCode(), be.getReason(), null);

        } else if (e instanceof BaseException be) {
            r = R.error(be.getCode(), be.getReason(), null);
        } else if (e instanceof ValidationException) {
            r = R.error(ExceptionEnum.PARAM_NOT_VALID.getCode(), e.getMessage(), null);
        } else if (e instanceof HttpRequestMethodNotSupportedException) {
            //请求方式错误
            r = R.error(ExceptionEnum.WRONG_REQ_METHOD, null);

        } else if (e instanceof HttpMediaTypeNotSupportedException) {
            //请求体错误
            r = R.error(ExceptionEnum.WRONG_REQ_BODY, null);

        } else if (e instanceof MissingServletRequestParameterException) {
            //缺少参数
            r = R.error(ExceptionEnum.REQUIR_NECESSARY_PARAM, null);

        } else if (e instanceof SQLIntegrityConstraintViolationException) {
            //违反唯一约束
            r = R.error(ExceptionEnum.DATA_DUPLICATE, null);

        } else if (e instanceof HttpMessageNotReadableException || e instanceof BindException) {
            //数据格式错误
            r = R.error(ExceptionEnum.WRONG_DATA_PATTERN, null);

        } else if (e instanceof MaxUploadSizeExceededException) {
            r = R.error(ExceptionEnum.FILE_TOO_LARGE_EX, null, multipartProperties.getMaxFileSize().toMegabytes());
        } else if (e instanceof NoHandlerFoundException) {
            r = R.error(ExceptionEnum.INVALID_URI);
        } else {
            r = R.error(ExceptionEnum.OP_FAIL);
        }
        log.error("异常信息：{}", r, e);
        return r;
    }
}
